package nccloud.mob.riart.message.actions;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Stack;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import itf.approvecenter.util.DataExchangeBean;
import nc.bs.dao.BaseDAO;
import nc.bs.dao.DAOException;
import nc.bs.framework.common.NCLocator;
import nc.bs.logging.Logger;
import nc.bs.pf.pub.PfDataCache;
import nc.bs.wfengine.engine.ActivityInstance;
import nc.itf.pub.workflowqry.IFlowInstanceQuery;
import nc.itf.uap.pf.IPFWorkflowQry;
import nc.itf.uap.pf.IWorkflowDefine;
import nc.itf.uap.pf.IWorkflowMachine;
import nc.jdbc.framework.processor.BeanProcessor;
import nc.vo.ml.NCLangRes4VoTransl;
import nc.vo.pub.AggregatedValueObject;
import nc.vo.pub.BusinessException;
import nc.vo.pub.workflownote.WorkflownoteVO;
import nc.vo.pub.workflowqry.FlowHistoryQryResult;
import nc.vo.uap.wfmonitor.ProcessRouteRes;
import nc.vo.wfengine.core.activity.Activity;
import nc.vo.wfengine.core.activity.GenericActivityEx;
import nc.vo.wfengine.core.parser.XPDLParserException;
import nc.vo.wfengine.core.transition.BasicTransitionEx;
import nc.vo.wfengine.core.workflow.BasicWorkflowProcess;
import nc.vo.wfengine.core.workflow.WorkflowProcess;
import nc.vo.wfengine.definition.ActivityTypeEnum;
import nc.vo.wfengine.definition.WorkflowTypeEnum;
import nc.vo.wfengine.pub.WFTask;
import nc.vo.wfengine.pub.WfTaskOrInstanceStatus;
import nc.vo.wfengine.pub.WfTaskType;
import nccloud.base.exception.ExceptionUtils;
import nccloud.baseapp.core.log.NCCForUAPLogger;
import nccloud.bs.message.itf.IMessageSyncService;
import nccloud.commons.lang.StringUtils;
import nccloud.framework.mob.action.itf.IMobileAction;
import nccloud.framework.mob.container.IMobRequest;
import nccloud.framework.mob.container.MobClientInfo;
import nccloud.framework.service.ServiceLocator;
import nccloud.framework.web.action.itf.ICommonAction;
import nccloud.framework.web.container.IRequest;
import nccloud.framework.web.container.SessionContext;
import nccloud.itf.uap.pf.NCCWorkFlowService;
import nccloud.message.vo.NCCMessageVO;
import nccloud.utils.mobile_riart.MessageLogger;
import nccloud.utils.riart.MessageEventTypeEnum;
import nccloud.vo.pf.flowinstance.NCCFlowInstanceVO;
import nccloud.web.workflow.approvalcenter.action.ApproveOrSignalActionUtil;
import nccloud.web.workflow.approvalcenter.action.PfChecknoteEnum;
import nccloud.web.workflow.approve.util.NCCFlowUtils;
import nccloud.web.workflow.approve.util.NCCMsgContext;

public class ApproveRejectAction implements ICommonAction, IMobileAction {
	public ApproveRejectAction() {
	}

	@Override
	public Object doAction(IRequest request) {
		String jsonStr = request.read();
		String cuserid = SessionContext.getInstance().getClientInfo().getUserid();
		return this.doApproveReject(jsonStr, cuserid, false);
	}

	@Override
	public Object doAction(IMobRequest req) {
		String jsonStr = req.read();
		String cuserid = (new MobClientInfo()).getUserid();
		return this.doApproveReject(jsonStr, cuserid, true);
	}

	private static Map<String, Activity> findAfterActivity(Activity act) {
		Stack<Activity> findActs = new Stack();
		Map<String, String> hasFind = new HashMap();
		Map<String, Activity> afterActs = new HashMap();
		findActs.push(act);

		while(!findActs.isEmpty()) {
			Activity a = findActs.pop();
			hasFind.put(a.getId(), a.getId());
			Map transMap = a.getEfferentTransitions();
			Iterator ite = transMap.entrySet().iterator();

			while(ite.hasNext()) {
				Entry next = (Entry)ite.next();
				BasicTransitionEx tran = (BasicTransitionEx)next.getValue();
				if (tran != null) {
					Activity toAct = tran.getToActivity();
					if (!hasFind.containsKey(toAct.getId())) {
						findActs.push(toAct);
					}

					if (!afterActs.containsKey(toAct.getId())) {
						afterActs.put(toAct.getId(), toAct);
					}
				}
			}
		}

		return afterActs;
	}

	private void IsCanRejectSSC(String reject_activity, String billId, String billType, WorkflownoteVO note) {
		NCCWorkFlowService nccWorkFlowService = ServiceLocator.find(NCCWorkFlowService.class);

		try {
			IFlowInstanceQuery iflowinstance = ServiceLocator.find(IFlowInstanceQuery.class);
			NCCFlowInstanceVO[] instances = iflowinstance.findFlowInstancesByBillIdAndBillTypeAppendOrderByCondition(billId, billType);
			if (instances != null && instances.length > 0) {
				billId = instances[0].getBillversionpk();
			} else {
				ExceptionUtils.wrapBusinessException(NCLangRes4VoTransl.getNCLangRes().getStrByID("0020nccloud_0", "0ncc0020001-0433"));
			}

			ProcessRouteRes processRoute = ServiceLocator.find(IWorkflowDefine.class).queryProcessRoute(billId, billType, (String)null, Integer.valueOf(instances[0].getWorkflow_type()));
			ActivityInstance[] actInsAry = processRoute.getActivityInstance();
			new HashMap();
			List<String> actInfos = new ArrayList();
			Map<String, Activity> afterShareActInfos = new HashMap();
			boolean isAfterShareCenter = false;
			boolean isFirstExamAct = false;
			int sscReviewActExam = 0;
			ActivityInstance[] var16 = actInsAry;
			int var17 = actInsAry.length;

			for(int var18 = 0; var18 < var17; ++var18) {
				ActivityInstance actIns = var16[var18];
				if (actIns.getStatus() != 4) {
					Activity actObject = null;

					try {
						actObject = PfDataCache.getWorkflowProcess(instances[0].getProcessdefid()).findActivityByID(actIns.getActivityID());
					} catch (XPDLParserException var23) {
						NCCForUAPLogger.error(var23.getMessage(), var23);
						nccloud.framework.core.exception.ExceptionUtils.wrapException(var23);
					}

					if (actObject instanceof GenericActivityEx) {
						GenericActivityEx act = (GenericActivityEx)actObject;
						String actType = nccWorkFlowService.getActivityType(act, billType);
						if (StringUtils.isNotEmpty(actType)) {
							if (isAfterShareCenter) {
								afterShareActInfos.put(actObject.getId(), actObject);
							}

							if (actType.equals("sscFirstExam")) {
								isAfterShareCenter = true;
								if (actObject.getId().equals(reject_activity)) {
									isFirstExamAct = true;
								}

								if (!afterShareActInfos.containsKey(actObject.getId())) {
									afterShareActInfos.put(actObject.getId(), actObject);
								}

								actInfos.add(act.getId());
							} else if (actType.equals("sscReview")) {
								isAfterShareCenter = true;
								if (!afterShareActInfos.containsKey(actObject.getId())) {
									afterShareActInfos.put(actObject.getId(), actObject);
								}

								sscReviewActExam = 1;
								actInfos.add(act.getId());
							}
						} else if (isAfterShareCenter) {
							if (!afterShareActInfos.containsKey(actObject.getId())) {
								afterShareActInfos.put(actObject.getId(), actObject);
							}

							actInfos.add(act.getId());
						}
					}
				}
			}

			if (actInfos.size() > 0) {
			}
		} catch (BusinessException var24) {
			NCCForUAPLogger.error(var24.getMessage(), var24);
			ExceptionUtils.wrapException(var24);
		}

	}

	private Object doApproveReject(String jsonStr, String cuserid, boolean isMobile) {
		DataExchangeBean bean = new DataExchangeBean();
		bean.setCode("200");
		String billType = "";
		String billId = "";
		String pk_checkflow = "";
		String reject_activity = "";
		String check_note = "";
		boolean isCanRejectActity = false;
		int workflowtype = WorkflowTypeEnum.Approveflow.getIntValue();
		String old_billId = "";
		NCCMsgContext nccMsg = new NCCMsgContext(jsonStr);
		JSONObject json2 = JSON.parseObject(jsonStr);
		boolean isTrack = false;
		if (json2.get("isTrack") != null) {
			isTrack = json2.getBoolean("isTrack");
		}

		Map<String, Object> msgInfoMap = nccMsg.getMsgINfoContext();
		String[] flowParameterArray = new String[]{"billtype", "billid", "pk_checkflow"};
		if (NCCFlowUtils.isFlowParameterArrayNull(flowParameterArray, msgInfoMap)) {
			return NCCFlowUtils.exchangeDataMsg(bean, "500", NCLangRes4VoTransl.getNCLangRes().getStrByID("0020nccloud_0", "0ncc0020001-0428"));
		} else {
			billType = msgInfoMap.get("billtype").toString();
			old_billId = msgInfoMap.get("billid").toString();
			billId = msgInfoMap.get("billid").toString();
			pk_checkflow = msgInfoMap.get("pk_checkflow").toString();

			// start edit by wy 20230612
			updateApproveRejectMessage(pk_checkflow);
			//end edit by wy
			
			NCCFlowUtils.checkIsExistMessage(billType, billId, cuserid);
			AggregatedValueObject billvo = null;
			IWorkflowMachine machine = ServiceLocator.find(IWorkflowMachine.class);
			NCCWorkFlowService nccWorkFlowService = ServiceLocator.find(NCCWorkFlowService.class);

			try {
				//				if (!isMobile && StringUtils.isNotBlank(pk_checkflow)) {
				//					String pk_group = nccWorkFlowService.getGroupByPKCheckFlow(pk_checkflow);
				//					if (StringUtils.isNotBlank(pk_group)) {
				//						SessionContext.getInstance().getClientInfo().setPk_group(pk_group);
				//					}
				//				}

				billvo = nccWorkFlowService.mobileAppUtilForQueryBillEntity(billType, billId);
			} catch (BusinessException var50) {
				ExceptionUtils.wrapBusinessException(NCLangRes4VoTransl.getNCLangRes().getStrByID("0020nccloud_0", "0ncc0020001-0430"));
			}

			try {
				NCCFlowInstanceVO[] resultInstance = ServiceLocator.find(IFlowInstanceQuery.class).findFlowInstancesByBillIdAndBillTypeAppendOrderByCondition(billId, billType);
				if (resultInstance == null || resultInstance.length == 0) {
					return null;
				}

				billId = resultInstance[0].getBillversionpk();
				workflowtype = Integer.valueOf(resultInstance[0].getWorkflow_type());
			} catch (BusinessException var55) {
				ExceptionUtils.wrapException(var55);
			}

			String rejecttype = "";
			if (msgInfoMap.get("rejecttype") != null && msgInfoMap.get("rejecttype").toString() != "") {
				rejecttype = msgInfoMap.get("rejecttype").toString();
			}

			if (msgInfoMap.get("pk_wf_task") != null) {
				reject_activity = String.valueOf(msgInfoMap.get("pk_wf_task"));
			} else {
				reject_activity = null;
			}

			if (msgInfoMap.get("checknote") != null) {
				check_note = String.valueOf(msgInfoMap.get("checknote"));
			}

			WorkflownoteVO note = null;

			try {
				note = nccWorkFlowService.checkWorkflowActions(billType, billId, pk_checkflow);
			} catch (BusinessException var49) {
				ExceptionUtils.wrapException(var49);
			}

			if (note == null) {
				ExceptionUtils.wrapBusinessException("WorkflownoteVO is null");
			}

			if (note != null) {
				note.setTrack(isTrack);
			}

			FlowHistoryQryResult result = null;

			try {
				result = ServiceLocator.find(IPFWorkflowQry.class).queryFlowHistoryQryResult(billType, billId, workflowtype);
			} catch (BusinessException var48) {
				ExceptionUtils.wrapException(var48);
			}

			ActivityInstance[] var26;
			int workflow_type;
			ActivityInstance[] actInsAry;
			ProcessRouteRes processRoute;
			if (StringUtils.isNotEmpty(reject_activity) && result != null) {
				processRoute = result.getProcessRoute();
				int var28;
				if (processRoute != null && processRoute.getActivityInstance() != null && processRoute.getActivityInstance().length > 0) {
					var26 = processRoute.getActivityInstance();
					workflow_type = var26.length;

					for(var28 = 0; var28 < workflow_type; ++var28) {
						ActivityInstance acinst = var26[var28];
						if (acinst.getStatus() == WfTaskOrInstanceStatus.Finished.getIntValue() && reject_activity.equals(acinst.getActivityID())) {
							isCanRejectActity = true;
						}
					}
				}

				if (processRoute != null && processRoute.getSubProcessRoute() != null && processRoute.getSubProcessRoute().length > 0) {
					ProcessRouteRes[] var58 = processRoute.getSubProcessRoute();
					workflow_type = var58.length;

					for(var28 = 0; var28 < workflow_type; ++var28) {
						processRoute = var58[var28];
						if (processRoute != null && processRoute.getActivityInstance() != null && processRoute.getActivityInstance().length > 0) {
							actInsAry = processRoute.getActivityInstance();
							int var31 = actInsAry.length;

							for(int var32 = 0; var32 < var31; ++var32) {
								ActivityInstance acinst = actInsAry[var32];
								if (acinst.getStatus() == WfTaskOrInstanceStatus.Finished.getIntValue() && reject_activity.equals(acinst.getActivityID())) {
									isCanRejectActity = true;
								}
							}
						}
					}
				}
			}

			if (!isCanRejectActity && StringUtils.isNotEmpty(reject_activity)) {
				ExceptionUtils.wrapBusinessException(NCLangRes4VoTransl.getNCLangRes().getStrByID("pfworkflow", "ApproveFlowRejectPanel-000000"));
			}

			String submit2RejectTache = "";

			try {
				submit2RejectTache = msgInfoMap.get("submit2RejectTache").toString();
			} catch (Exception var47) {
				Logger.error(var47);
			}

			var26 = null;

			try {
				WFTask currentTask = machine.getWFTask(note.getPk_wf_task());
				if (submit2RejectTache.equals("Y")) {
					note.getTaskInfo().getTask().setSubmit2RjectTache(true);
				}

				note.getTaskInfo().getTask().setTaskType(WfTaskType.Backward.getIntValue());
				NCCFlowUtils.checkIsCopySend(note, JSON.parseObject(jsonStr));
				if ("before".equals(rejecttype)) {
					boolean isSubflow = false;
					List<Activity> activitys = new ArrayList();
					processRoute = ServiceLocator.find(IWorkflowDefine.class).queryProcessRoute(billId, billType, (String)null, note.getWorkflow_type());
					actInsAry = processRoute.getActivityInstance();
					BasicWorkflowProcess basicwfp = null;

					try {
						basicwfp = PfDataCache.getWorkflowProcess(currentTask.getWfProcessDefPK());
					} catch (XPDLParserException var46) {
						nccloud.framework.core.exception.ExceptionUtils.wrapException(var46);
					}

					if (note.getWorkflow_type() != 2 && note.getWorkflow_type() != 4) {
						isSubflow = true;
						List<Activity> list = basicwfp.getActivities();
						Iterator var74 = list.iterator();

						while(var74.hasNext()) {
							Activity act = (Activity)var74.next();
							if (act.getActivityType() != ActivityTypeEnum.Route.getIntValue() && act.getActivityType() != ActivityTypeEnum.Auto.getIntValue()) {
								if (act.getId().equals(basicwfp.findActivityByID(currentTask.getActivityID()).getId())) {
									break;
								}

								activitys.add(act);
							}
						}
					} else {
						ActivityInstance[] var70 = actInsAry;
						int var73 = actInsAry.length;

						for(int var75 = 0; var75 < var73; ++var75) {
							ActivityInstance actins = var70[var75];
							if (actins.getStatus() != 4 && actins.getStatus() != 0 && basicwfp.findActivityByID(actins.getActivityID()).getActivityType() != ActivityTypeEnum.Route.getIntValue() && basicwfp.findActivityByID(actins.getActivityID()).getActivityType() != ActivityTypeEnum.Auto.getIntValue()) {
								if (actins.getActivityID().equals(basicwfp.findActivityByID(currentTask.getActivityID()).getId())) {
									break;
								}

								activitys.add(basicwfp.findActivityByID(actins.getActivityID()));
							}
						}
					}

					if (isSubflow && activitys.size() == 0) {
						nccloud.framework.core.exception.ExceptionUtils.wrapBusinessException(NCLangRes4VoTransl.getNCLangRes().getStrByID("0020nccloud_0", "0ncc0020001-0432"));
					} else {
						note.getTaskInfo().getTask().setJumpToActivity(activitys.get(activitys.size() - 1).getId());
					}

					this.IsCanRejectSSC(activitys.get(activitys.size() - 1).getId(), old_billId, billType, note);
				} else if ("billmake".equals(rejecttype)) {
					IFlowInstanceQuery iflowinstance = ServiceLocator.find(IFlowInstanceQuery.class);
					NCCFlowInstanceVO[] instances = iflowinstance.findFlowInstancesByBillIdAndBillType(billId, billType);
					if (instances != null && instances.length != 0) {
						try {
							WorkflowProcess wf = PfDataCache.getWorkflowProcess(instances[0].getProcessdefid());
							Activity startActivity = wf.findStartActivity();
							note.getTaskInfo().getTask().setJumpToActivity(startActivity.getId());
							this.IsCanRejectSSC(startActivity.getId(), old_billId, billType, note);
						} catch (XPDLParserException var45) {
							ExceptionUtils.wrapException(var45);
						}
					} else {
						nccloud.framework.core.exception.ExceptionUtils.wrapBusinessException(NCLangRes4VoTransl.getNCLangRes().getStrByID("0020nccloud_0", "0ncc0020001-0433"));
					}
				} else if (reject_activity != null && !"".equals(reject_activity)) {
					workflow_type = note.getWorkflow_type();
					String var63 = "";

					try {
						processRoute = ServiceLocator.find(IWorkflowDefine.class).queryProcessRoute(billId, billType, (String)null, workflow_type);
						actInsAry = processRoute.getActivityInstance();
						new HashMap();
						List<String> actInfos = new ArrayList();
						Map<String, Activity> afterShareActInfos = new HashMap();
						boolean isAfterShareCenter = false;
						int sscReviewActExam = 0;
						boolean isFirstExamAct = false;
						if (actInsAry != null && actInsAry.length > 0) {
							ActivityInstance[] var37 = actInsAry;
							int var38 = actInsAry.length;

							for(int var39 = 0; var39 < var38; ++var39) {
								ActivityInstance actIns = var37[var39];
								if (actIns.getStatus() != 4) {
									Activity actObject = null;

									try {
										actObject = PfDataCache.getWorkflowProcess(note.getTaskInfo().getTask().getWfProcessDefPK()).findActivityByID(actIns.getActivityID());
									} catch (XPDLParserException var44) {
										NCCForUAPLogger.error(var44.getMessage(), var44);
										nccloud.framework.core.exception.ExceptionUtils.wrapException(var44);
									}

									if (actObject instanceof GenericActivityEx) {
										GenericActivityEx act = (GenericActivityEx)actObject;
										String actType = nccWorkFlowService.getActivityType(act, billType);
										if (StringUtils.isNotEmpty(actType)) {
											if (isAfterShareCenter) {
												afterShareActInfos.put(actObject.getId(), actObject);
											}

											if (actType.equals("sscFirstExam")) {
												isAfterShareCenter = true;
												if (actObject.getId().equals(reject_activity)) {
													isFirstExamAct = true;
												}

												if (!afterShareActInfos.containsKey(actObject.getId())) {
													afterShareActInfos.put(actObject.getId(), actObject);
												}

												actInfos.add(act.getId());
											} else if (actType.equals("sscReview")) {
												isAfterShareCenter = true;
												if (!afterShareActInfos.containsKey(actObject.getId())) {
													afterShareActInfos.put(actObject.getId(), actObject);
												}

												sscReviewActExam = 1;
												actInfos.add(act.getId());
											}
										} else if (isAfterShareCenter) {
											if (!afterShareActInfos.containsKey(actObject.getId())) {
												afterShareActInfos.put(actObject.getId(), actObject);
											}

											actInfos.add(act.getId());
										}
									}
								}
							}
						}

						if (actInfos.size() > 0) {
							if (!afterShareActInfos.containsKey(reject_activity)) {
								ExceptionUtils.wrapBusinessException(NCLangRes4VoTransl.getNCLangRes().getStrByID("0020nccloud_0", "0ncc0020001-0434"));
							}

							if (!isFirstExamAct || sscReviewActExam == 0) {
							}
						}
					} catch (BusinessException var52) {
						NCCForUAPLogger.error(var52.getMessage(), var52);
						ExceptionUtils.wrapException(var52);
					}

					note.getTaskInfo().getTask().setBackToFirstActivity(false);
					note.getTaskInfo().getTask().setJumpToActivity(reject_activity);
				} else {
					note.getTaskInfo().getTask().setJumpToActivity((String)null);
					note.getTaskInfo().getTask().setBackToFirstActivity(true);
					this.IsCanRejectSSC(reject_activity, old_billId, billType, note);
				}

				note.setApproveresult("R");
				if (StringUtils.isEmpty(check_note)) {
					check_note = NCCFlowUtils.getIndividualCheckNote(PfChecknoteEnum.REJECT, cuserid);
					note.setChecknote(check_note);
				} else {
					note.setChecknote(check_note);
				}

				note.getTaskInfo().getTask().setTaskType(WfTaskType.Backward.getIntValue());
			} catch (BusinessException var53) {
				ExceptionUtils.wrapException(var53);
			} catch (Exception var54) {
				ExceptionUtils.wrapException(var54);
			}

			try {
				NCCFlowUtils.handleAttrfiles(json2, note);
				if (note.getWorkflow_type() != WorkflowTypeEnum.Approveflow.getIntValue() && note.getWorkflow_type() != WorkflowTypeEnum.SubApproveflow.getIntValue()) {
					ApproveOrSignalActionUtil.processAction("SIGNAL", billType, note, billvo, (Object)null, (HashMap)null, (String)null);
				} else {
					ApproveOrSignalActionUtil.processAction("APPROVE", billType, note, billvo, (Object)null, (HashMap)null, (String)null);
				}
			} catch (Exception var51) {
				ExceptionUtils.wrapException(var51);
			}

			return bean;
		}
	}

	//satrt eidt wy by 20230612
	/**
	* 修改消息推送第三方
	* @param pk_datail 消息详情主键
	* @throws DAOException
	 *
	*/
	public void updateApproveRejectMessage(String pk_datail) {
		MessageLogger.info("进入 【nccloud.web.workflow.approvalcenter.action.ApproveRejectAction】 类中方法【updateApproveRejectMessage】 ");
		try {
			NCCMessageVO tempMsgVos = (NCCMessageVO)new BaseDAO().executeQuery("select * from sm_msg_approve where pk_detail = '"+pk_datail+"'", 
					new BeanProcessor(NCCMessageVO.class)); 
			ServiceLocator.find(IMessageSyncService.class).setMessageCache(new NCCMessageVO[] {tempMsgVos}, MessageEventTypeEnum.UPDATE);
		}catch(Exception e) {
			MessageLogger.error("已读消息推送第三方失败【nccloud.web.workflow.approvalcenter.action.ApproveRejectAction】，失败原因: " + e.getMessage());
		}
		
	}
	//end by wy
}